package com.kuang.unsafe;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Set 单线程下是安全的，并发情况下不安全。
 * 并发情况下，有些集合类会报错：并发修改异常  ConcurrentModificationException
 *
 * 解决办法：
 *  方式1 工具类Collections.synchronizedSet
 *  方式2 写入时复制 new CopyOnWriteArraySet<>()
 *
 *
 *  hashSet底层时什么？
 *      public HashSet() {
 *         map = new HashMap<>();
 *      }
*       // set.add  set本质是map,key无法重复！
*       public boolean add(E e) {
*           return map.put(e, PRESENT)==null;
*       }
*       // 不变的值
*       private static final Object PRESENT = new Object();
 */
public class SetTest {
    public static void main(String[] args) {

        // 单线程下，没有问题
        //HashSet<Object> set = new HashSet<>();
        //for (int i = 0; i < 1000; i++) {
        //    set.add(UUID.randomUUID().toString().substring(0,5));
        //    System.out.println(set);
        //}

        // 多线程下，并发修改异常
        //Set<Object> set = new HashSet<>();
        //for (int i = 0; i < 1000; i++) {
        //    new Thread(()->{
        //        set.add(UUID.randomUUID().toString().substring(0,5));
        //        System.out.println(set);
        //    }, String.valueOf(i)).start();
        //}

        // 方式1 工具类Collections.synchronizedSet
        //Set<Object> set = Collections.synchronizedSet(new HashSet<>());
        //for (int i = 0; i < 1000; i++) {
        //    new Thread(()->{
        //        set.add(UUID.randomUUID().toString().substring(0,5));
        //        System.out.println(set);
        //    }, String.valueOf(i)).start();
        //}

        // 方式2 写入时复制 new CopyOnWriteArraySet<>()
        Set<Object> set = new CopyOnWriteArraySet<>();
        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            }, String.valueOf(i)).start();
        }

    }

}
